class Watcher{
    constructor(vm,expr,callback){
        this.vm = vm
        this.expr = expr
        this.callback = callback//更新回调
        this.oldVal = this.getOldVal()
    }
    getOldVal(){
        //把观察者挂载到
        Dep.target = this
        //data[currentVal] 调用getter()，getter方法中判断有Dep.target 则添加依赖
        const oldVal = compileUtil.getVal(this.expr,this.vm)
        Dep.target = null//用完后销毁掉
        return oldVal;
    }
    update(){
        //此时调用getter()不添加依赖，因为getOldVal里已经添加过了
        const newVal = compileUtil.getVal(this.expr,this.vm)
        if(newVal !== this.oldVal){
            this.callback(newVal)
        }
    }
}
class Dep{//收集依赖器 Watcher数组
    constructor(){
        this.subs = []
    }
    //收集观察者
    addSub(watcher){
        this.subs.push(watcher)
    }
    //通知所有此依赖的观察者去更新
    notify(){
        console.log('观察者',this.subs)
        this.subs.forEach(w=>w.update())
    }
}
class Observer{//数据劫持
    constructor(data){
        this.observe(data);
    }
    observe(data){
        if(data && typeof data === "object"){
            console.log(Object.keys(data)) 
            Object.keys(data).forEach(key=>{
                this.defineReactive(data,key,data[key])
            })
        }
    }
    defineReactive(obj,key,value){//劫持并监听所有的属性
        this.observe(value);//是对象则递归调用
        const dep = new Dep()//闭包：被内部函数引用
        Object.defineProperty(obj,key,{
            enumerable:true,
            configurable:false,
            get(){
                //初始化
                //编译时，遇到{{msg}}走这里
                //订阅数据变化时，往Dep中添加观察者
                if(Dep.target){
                    dep.addSub(Dep.target)//添加依赖
                }
                return value;
            },
            set:(newVal)=>{
                console.log('defineReactive:',newVal)
                this.observe(newVal)
                if(newVal != value){
                    value = newVal
                }
                //告诉Dep通知变化 派发更新
                dep.notify()
            }
        })
    }
}